maxLineLength = SniffSettingsHelper::normalizeInteger($this->maxLineLength); if (!$this->isCall($phpcsFile, $stringPointer)) { return; } if ($this->shouldBeSkipped($phpcsFile, $stringPointer)) { return; } $tokens = $phpcsFile->getTokens(); $parenthesisOpenerPointer = TokenHelper::findNextEffective($phpcsFile, $stringPointer + 1); $parenthesisCloserPointer = $tokens[$parenthesisOpenerPointer]['parenthesis_closer']; if ($tokens[$parenthesisOpenerPointer]['line'] === $tokens[$parenthesisCloserPointer]['line']) { return; } if (TokenHelper::findNext( $phpcsFile, array_merge(TokenHelper::INLINE_COMMENT_TOKEN_CODES, Tokens::$heredocTokens), $parenthesisOpenerPointer + 1, $parenthesisCloserPointer, ) !== null) { return; } for ($i = $parenthesisOpenerPointer + 1; $i < $parenthesisCloserPointer; $i++) { if ($tokens[$i]['code'] !== T_CONSTANT_ENCAPSED_STRING && $tokens[$i]['code'] !== T_DOUBLE_QUOTED_STRING) { continue; } if (strpos($tokens[$i]['content'], $phpcsFile->eolChar) !== false) { return; } } if ($this->ignoreWithComplexParameter) { if ( TokenHelper::findNext( $phpcsFile, [T_CLOSURE, T_FN, T_OPEN_SHORT_ARRAY], $parenthesisOpenerPointer + 1, $parenthesisCloserPointer, ) !== null ) { return; } // Contains inner call $callSearchStartPointer = $parenthesisOpenerPointer + 1; while (true) { $innerStringPointer = TokenHelper::findNext( $phpcsFile, TokenHelper::ONLY_NAME_TOKEN_CODES, $callSearchStartPointer, $parenthesisCloserPointer, ); if ($innerStringPointer === null) { break; } $pointerAfterInnerString = TokenHelper::findNextEffective($phpcsFile, $innerStringPointer + 1); if ( $pointerAfterInnerString !== null && $tokens[$pointerAfterInnerString]['code'] === T_OPEN_PARENTHESIS ) { return; } $callSearchStartPointer = $innerStringPointer + 1; } } $lineStart = $this->getLineStart($phpcsFile, $parenthesisOpenerPointer); $call = $this->getCall($phpcsFile, $parenthesisOpenerPointer, $parenthesisCloserPointer); $lineEnd = $this->getLineEnd($phpcsFile, $parenthesisCloserPointer); $lineLength = strlen($lineStart . $call . $lineEnd); if (!$this->shouldReportError($lineLength)) { return; } $previousPointer = TokenHelper::findPreviousEffective($phpcsFile, $stringPointer - 1); $name = ltrim($tokens[$stringPointer]['content'], '\\'); if (in_array($tokens[$previousPointer]['code'], [T_OBJECT_OPERATOR, T_DOUBLE_COLON], true)) { $error = sprintf('Call of method %s() should be placed on a single line.', $name); } elseif ($tokens[$previousPointer]['code'] === T_NEW) { $error = 'Constructor call should be placed on a single line.'; } else { $error = sprintf('Call of function %s() should be placed on a single line.', $name); } $fix = $phpcsFile->addFixableError($error, $stringPointer, self::CODE_REQUIRED_SINGLE_LINE_CALL); if (!$fix) { return; } $phpcsFile->fixer->beginChangeset(); FixerHelper::add($phpcsFile, $parenthesisOpenerPointer, $call); FixerHelper::removeBetween($phpcsFile, $parenthesisOpenerPointer, $parenthesisCloserPointer); $phpcsFile->fixer->endChangeset(); } private function shouldBeSkipped(File $phpcsFile, int $stringPointer): bool { $tokens = $phpcsFile->getTokens(); foreach (array_reverse(TokenHelper::findNextAll($phpcsFile, [T_OPEN_PARENTHESIS, T_FUNCTION], 0, $stringPointer)) as $pointer) { if ($tokens[$pointer]['code'] === T_FUNCTION) { if (array_key_exists('scope_closer', $tokens[$pointer]) && $tokens[$pointer]['scope_closer'] > $stringPointer) { return false; } continue; } if ($tokens[$pointer]['parenthesis_closer'] < $stringPointer) { continue; } $pointerBeforeParenthesisOpener = TokenHelper::findPreviousEffective($phpcsFile, $pointer - 1); if ( $pointerBeforeParenthesisOpener === null || $tokens[$pointerBeforeParenthesisOpener]['code'] !== T_STRING ) { continue; } return true; } return false; } private function shouldReportError(int $lineLength): bool { if ($this->maxLineLength === 0) { return true; } return $lineLength <= $this->maxLineLength; } }